/* 
基础数据类型
1. boolean
2. number
3. string
4. null和undefined
5. 数组
6. 元组(Tuple) 
7. 枚举(enum)
8. any
9. void
10. object
*/

(function () {
  // 1. boolean
  let isDone: boolean = false
  isDone = true
  // isDone = 3 // error

  // 2. number
  let age: number = 3
  age = 23
  // age = 'abc'  // error

  // 3. string
  let name: string = 'tom'
  name = 'jack'
  // name = {} // error
  let info: string = `我叫${name}, 今年${age}`

  // 4. null和undefined
  // null只有一个值 null, undefined类型也只有一个值undefined   null和undefined是任意其它类型的子类型
  let n: null = null
  // n = 'abc'  // error
  let u: undefined = undefined
  // u = 3  // error
  info = null   // 将一个子类型值赋值给一个父类型的变量
  info = undefined

  // 5. 数组
  let arr1: number[] = [1, 3/* , 'abc' */]
  arr1.push(4)
  // arr1.push(true) // error
  let arr2: Array<string> = ['a','123'/* , 123 */]

  // 6. 元组(Tuple) 
  // 特别的数组: 元素的个数和类型都是确定的
  let ageName: [number, string]  // 包含2个元素, 第一个是number类型, 第二个是string类型
  ageName = [12, 'abc']


  // 7. 枚举(enum)
  enum Color {
    Red,   // 0
    Yellow = 3,
    Blue // 4
  }
  console.log(Color)
  console.log(Color.Red)

  let myColor: Color = Color.Red
  // myColor = 5  // 不会报错, 不太好

  const cat = {
    name: 'marry',
    color: 2
  }

  switch (cat.color) {
    case Color.Red:
      console.log('你的猫是红色的')
      break;
    case Color.Yellow:
      console.log('你的猫是黄色的')
      break;
    case Color.Blue:
      console.log('你的猫是蓝色的')
      break;
    default:
      console.log('你的猫是其它颜色的')
  }

  // 8. any
  let a: any = 'abc'
  a = 123
  a = {}

  // 9. void   没有/不是任何类型  声明函数没有返回值
  function fn(): void {
    // return 3  // error
    // return 'abc' // error
    console.log('----')
    // return null
    return undefined
  }

  function fn2() {
    // return 2
    return {}
  }

  // 10. object
  function fn3(a: object): object {
    // 在js中: 函数体如果没有return, 相当于return undefined => 但在ts不是这样的
    // return undefined
    // return null
    // return {}
    // return () => {}
    return []
    // return 3  // error
  }

  // fn3(undefined)
  fn3(() => {})
})()
